//
//  BaseCodable.swift
//  FingerABC
//
//  Created by ming on 2025/2/26.
//

import Foundation

public typealias JSONable = BaseCodable & Codable
public protocol BaseCodable { }

extension BaseCodable where Self: Codable {
    public static func deserialize(dic: [String: Any]) -> Self? {
        do {
            let data = try JSONSerialization.data(withJSONObject: dic, options: [])
            return parser(data)
        } catch let jsonError {
            print("======Decoder Error============")
            print(jsonError)
        }
        return nil
    }
    
    public static func stringToModel(_ jsonString: String) -> Self? {
        guard let data = jsonString.data(using: String.Encoding.utf8, allowLossyConversion: false) else { return nil }
        return parser(data)
    }
    
    public static func parser(_ data: Data) -> Self? {
        do {
            return try JSONDecoder().decode(Self.self, from: data)
        } catch let jsonError {
            print("======Decoder Error============")
            print(jsonError)
            
            if let json = String(data: data, encoding: .utf8) {
                print(json)
            }
        }
        return nil
    }
    
    public func toJSON() -> [String: Any]? {
        do {
            let jsonData = try JSONEncoder().encode(self)
            return try JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers) as? [String: Any]
        } catch let jsonError {
            print("======Decoder Error============")
            print(jsonError)
        }
        return nil
    }
    
    public func toJSONString() -> String? {
        do {
            let jsonData = try JSONEncoder().encode(self)
            return String(data: jsonData, encoding: .utf8)
        } catch let jsonError {
            print("======Decoder Error============")
            print(jsonError)
        }
        return nil
    }
}

// MARK: - 本地存储本地
extension BaseCodable where Self: Codable {
    public func saved(key: String) {
        if let encoded = try? JSONEncoder().encode(self) {
            UserDefaults.standard.set(encoded, forKey: key)
        }
    }
    
    public static func deserialize(key: String) -> Self? {
        if let data = UserDefaults.standard.data(forKey: key) {
            if let decoded = try? JSONDecoder().decode(Self.self, from: data) {
                return decoded
            }
        }
        return nil
    }
    
    public static func deserializeJson(_ name: String) -> Self? {
        guard let path = Bundle.main.path(forResource: name, ofType: "json") else { return nil }
        guard let data = try? Data(contentsOf: URL(fileURLWithPath: path),options: .mappedIfSafe) else { return nil }
        return self.parser(data)
    }
}

